using Nzy3d.Colors;
using Nzy3d.Maths;
using Nzy3d.Plot3D.Rendering.View;
using Nzy3d.Plot3D.Text.Align;
using OpenTK.Graphics.OpenGL;

namespace Nzy3d.Plot3D.Text.Renderers
{
    /// <summary>
    /// A <see cref="TextBillboardRenderer"/> allows writing 2d text always facing the Camera of a 3d Scene.
    /// <br/>
    /// TextBillboard provides the pixel definition of all characters of
    /// the ASCII alphabet. A default bitmap (plain rectangle)
    /// is provided for unrecognized characters
    /// (those that do not have an ASCII code).
    /// The bitmap library is static, and thus no overhead is
    /// generated by the use of several instances of TextBillboard.
    /// <br/>
    /// It is however not necessary to have an instance of TextBillboard
    /// for each drawn string.
    /// <br/>
    /// <code>
    /// String s          = new String("2d text in 3d Scene");<br/>
    /// TextBillboard txt = new TextBillboard();<br/>
    /// BoundingBox3d box;<br/>
    /// <br/>
    /// txt.drawText(gl, s, Coord3d.ORIGIN, Halign.LEFT, Valign.GROUND, Color.BLACK);<br/>
    /// box = txt.drawText(gl, glu, cam, s, Coord3d.ORIGIN, Halign.LEFT, Valign.GROUND, Color.BLACK);<br/>
    /// </code>
    /// <br/>
    /// <b>Layout constants</b>
    /// <br/>
    /// As demonstrated in the previous example, the <see cref="TextBillboardRenderer"/>  handles
    /// vertical and horizontal layout of text according to the given text coordinate.
    /// <br/>
    /// The following picture illustrates the text layout when using
    /// the various layout constants
    /// <img src="plot3d/primitives/doc-files/TextBillboardBillboard-1.gif"/>
    /// @author Martin Pernollet
    /// </summary>
    public class TextBillboardRenderer : AbstractTextRenderer, ITextRenderer
	{
		// px heigth
		private const int charHeight = 13;

		// px width
		private const int charWidth = 8;

		// px between 2 characters
		private const int charOffset = 2;

		public TextBillboardRenderer() : base()
		{
		}

		public override void DrawSimpleText(Camera cam, string s, Coord3d position, Color color)
		{
			GL.Color3(color.R, color.G, color.B);
			GL.RasterPos3(position.X, position.Y, position.Z);
			PrintString(s, Halign.RIGHT, Valign.GROUND);
		}

		public override BoundingBox3d DrawText(Camera cam, string s, Coord3d position, Halign halign, Valign valign, Color color, Coord2d screenOffset, Coord3d sceneOffset)
		{
			GL.Color3(color.R, color.G, color.B);
			GL.RasterPos3(position.X, position.Y, position.Z);
			BillBoardSize dims = PrintString(s, halign, valign);
			Coord3d posScreen = cam.ModelToScreen(position);
			Coord3d botLeft = new Coord3d();
			Coord3d topRight = new Coord3d();
			botLeft.X = posScreen.X + dims.xoffset;
			botLeft.Y = posScreen.Y + dims.yoffset;
			botLeft.Z = posScreen.Z;
			topRight.X = botLeft.X + dims.xoffset;
			topRight.Y = botLeft.Y + dims.yoffset;
			topRight.Z = botLeft.Z;
			BoundingBox3d txtBounds = new BoundingBox3d();
			txtBounds.Add(cam.ScreenToModel(botLeft));
			txtBounds.Add(cam.ScreenToModel(topRight));
			return txtBounds;
		}

		private BillBoardSize PrintString(string s, Halign halign, Valign valign)
		{
			char[] acodes = s.ToCharArray();
			int nchar = s.Length;
			float xorig = 0;
			float yorig = 2;
			float xmove = charWidth + charOffset;
			float ymove = 0;

			// Compute horizontal alignment
			switch (halign)
			{
				case Halign.RIGHT:
					//xorig = xorig;
					break;

				case Halign.CENTER:
					xorig = nchar * xmove / 2;
					break;

				case Halign.LEFT:
					xorig = nchar * xmove;
					break;

				default:
					throw new Exception("Horizontal alignement constant unknown: " + halign);
			}

			// Compute vertical alignment
			switch (valign)
			{
				case Valign.TOP:
					yorig = 0;
					break;
				case Valign.GROUND:
					yorig = yorig;
					break;
				case Valign.CENTER:
					yorig = charHeight / 2;
					break;
				case Valign.BOTTOM:
					yorig = charHeight;
					break;
				default:
					throw new Exception("Vertical alignement constant unknown: " + valign);
			}

			// Draw the bitmaps
			GL.PixelStore(PixelStoreParameter.UnpackAlignment, 1);
            for (int c = 0; c <= acodes.Length - 1; c++)
			{
                int idx = acodes[c] - 32;
                if (idx < 0 || idx >= ascii.Length)
				{
					GL.Bitmap(charWidth, charHeight, xorig, yorig, xmove, ymove, nonascii);
				}
				else
				{
					GL.Bitmap(charWidth, charHeight, xorig, yorig, xmove, ymove, ascii[idx]);
				}
			}
			return new BillBoardSize(xmove * nchar, charHeight, -xorig, -yorig);
		}

		private class BillBoardSize
		{
			public float width;
			public float height;
			public float xoffset;

			public float yoffset;
			public BillBoardSize(float width, float height, float xoffset, float yoffset)
			{
				this.width = width;
				this.height = height;
				this.xoffset = xoffset;
				this.yoffset = yoffset;
			}
		}

		// each of the 95 line is a letter, each of the (charHeight) byte of a line represent a raw of (charWidth) pixels
		private static readonly byte[][] ascii = {
			new byte[] {
				0x0,
				0x0,
				0x0,
				0x0,
				0x0,
				0x0,
				0x0,
				0x0,
				0x0,
				0x0,
				0x0,
				0x0,
				0x0
			},
			new byte[] {
				0x0,
				0x0,
				0x18,
				0x18,
				0x0,
				0x0,
				0x18,
				0x18,
				0x18,
				0x18,
				0x18,
				0x18,
				0x18
			},
			new byte[] {
				0x0,
				0x0,
				0x0,
				0x0,
				0x0,
				0x0,
				0x0,
				0x0,
				0x0,
				0x36,
				0x36,
				0x36,
				0x36
			},
			new byte[] {
				0x0,
				0x0,
				0x0,
				0x66,
				0x66,
				0xff,
				0x66,
				0x66,
				0xff,
				0x66,
				0x66,
				0x0,
				0x0
			},
			new byte[] {
				0x0,
				0x0,
				0x18,
				0x7e,
				0xff,
				0x1b,
				0x1f,
				0x7e,
				0xf8,
				0xd8,
				0xff,
				0x7e,
				0x18
			},
			new byte[] {
				0x0,
				0x0,
				0xe,
				0x1b,
				0xdb,
				0x6e,
				0x30,
				0x18,
				0xc,
				0x76,
				0xdb,
				0xd8,
				0x70
			},
			new byte[] {
				0x0,
				0x0,
				0x7f,
				0xc6,
				0xcf,
				0xd8,
				0x70,
				0x70,
				0xd8,
				0xcc,
				0xcc,
				0x6c,
				0x38
			},
			new byte[] {
				0x0,
				0x0,
				0x0,
				0x0,
				0x0,
				0x0,
				0x0,
				0x0,
				0x0,
				0x18,
				0x1c,
				0xc,
				0xe
			},
			new byte[] {
				0x0,
				0x0,
				0xc,
				0x18,
				0x30,
				0x30,
				0x30,
				0x30,
				0x30,
				0x30,
				0x30,
				0x18,
				0xc
			},
			new byte[] {
				0x0,
				0x0,
				0x30,
				0x18,
				0xc,
				0xc,
				0xc,
				0xc,
				0xc,
				0xc,
				0xc,
				0x18,
				0x30
			},
			new byte[] {
				0x0,
				0x0,
				0x0,
				0x0,
				0x99,
				0x5a,
				0x3c,
				0xff,
				0x3c,
				0x5a,
				0x99,
				0x0,
				0x0
			},
			new byte[] {
				0x0,
				0x0,
				0x0,
				0x18,
				0x18,
				0x18,
				0xff,
				0xff,
				0x18,
				0x18,
				0x18,
				0x0,
				0x0
			},
			new byte[] {
				0x0,
				0x0,
				0x30,
				0x18,
				0x1c,
				0x1c,
				0x0,
				0x0,
				0x0,
				0x0,
				0x0,
				0x0,
				0x0
			},
			new byte[] {
				0x0,
				0x0,
				0x0,
				0x0,
				0x0,
				0x0,
				0xff,
				0xff,
				0x0,
				0x0,
				0x0,
				0x0,
				0x0
			},
			new byte[] {
				0x0,
				0x0,
				0x0,
				0x38,
				0x38,
				0x0,
				0x0,
				0x0,
				0x0,
				0x0,
				0x0,
				0x0,
				0x0
			},
			new byte[] {
				0x0,
				0x60,
				0x60,
				0x30,
				0x30,
				0x18,
				0x18,
				0xc,
				0xc,
				0x6,
				0x6,
				0x3,
				0x3
			},
			new byte[] {
				0x0,
				0x0,
				0x3c,
				0x66,
				0xc3,
				0xe3,
				0xf3,
				0xdb,
				0xcf,
				0xc7,
				0xc3,
				0x66,
				0x3c
			},
			new byte[] {
				0x0,
				0x0,
				0x7e,
				0x18,
				0x18,
				0x18,
				0x18,
				0x18,
				0x18,
				0x18,
				0x78,
				0x38,
				0x18
			},
			new byte[] {
				0x0,
				0x0,
				0xff,
				0xc0,
				0xc0,
				0x60,
				0x30,
				0x18,
				0xc,
				0x6,
				0x3,
				0xe7,
				0x7e
			},
			new byte[] {
				0x0,
				0x0,
				0x7e,
				0xe7,
				0x3,
				0x3,
				0x7,
				0x7e,
				0x7,
				0x3,
				0x3,
				0xe7,
				0x7e
			},
			new byte[] {
				0x0,
				0x0,
				0xc,
				0xc,
				0xc,
				0xc,
				0xc,
				0xff,
				0xcc,
				0x6c,
				0x3c,
				0x1c,
				0xc
			},
			new byte[] {
				0x0,
				0x0,
				0x7e,
				0xe7,
				0x3,
				0x3,
				0x7,
				0xfe,
				0xc0,
				0xc0,
				0xc0,
				0xc0,
				0xff
			},
			new byte[] {
				0x0,
				0x0,
				0x7e,
				0xe7,
				0xc3,
				0xc3,
				0xc7,
				0xfe,
				0xc0,
				0xc0,
				0xc0,
				0xe7,
				0x7e
			},
			new byte[] {
				0x0,
				0x0,
				0x30,
				0x30,
				0x30,
				0x30,
				0x18,
				0xc,
				0x6,
				0x3,
				0x3,
				0x3,
				0xff
			},
			new byte[] {
				0x0,
				0x0,
				0x7e,
				0xe7,
				0xc3,
				0xc3,
				0xe7,
				0x7e,
				0xe7,
				0xc3,
				0xc3,
				0xe7,
				0x7e
			},
			new byte[] {
				0x0,
				0x0,
				0x7e,
				0xe7,
				0x3,
				0x3,
				0x3,
				0x7f,
				0xe7,
				0xc3,
				0xc3,
				0xe7,
				0x7e
			},
			new byte[] {
				0x0,
				0x0,
				0x0,
				0x38,
				0x38,
				0x0,
				0x0,
				0x38,
				0x38,
				0x0,
				0x0,
				0x0,
				0x0
			},
			new byte[] {
				0x0,
				0x0,
				0x30,
				0x18,
				0x1c,
				0x1c,
				0x0,
				0x0,
				0x1c,
				0x1c,
				0x0,
				0x0,
				0x0
			},
			new byte[] {
				0x0,
				0x0,
				0x6,
				0xc,
				0x18,
				0x30,
				0x60,
				0xc0,
				0x60,
				0x30,
				0x18,
				0xc,
				0x6
			},
			new byte[] {
				0x0,
				0x0,
				0x0,
				0x0,
				0xff,
				0xff,
				0x0,
				0xff,
				0xff,
				0x0,
				0x0,
				0x0,
				0x0
			},
			new byte[] {
				0x0,
				0x0,
				0x60,
				0x30,
				0x18,
				0xc,
				0x6,
				0x3,
				0x6,
				0xc,
				0x18,
				0x30,
				0x60
			},
			new byte[] {
				0x0,
				0x0,
				0x18,
				0x0,
				0x0,
				0x18,
				0x18,
				0xc,
				0x6,
				0x3,
				0xc3,
				0xc3,
				0x7e
			},
			new byte[] {
				0x0,
				0x0,
				0x3f,
				0x60,
				0xcf,
				0xdb,
				0xd3,
				0xdd,
				0xc3,
				0x7e,
				0x0,
				0x0,
				0x0
			},
			new byte[] {
				0x0,
				0x0,
				0xc3,
				0xc3,
				0xc3,
				0xc3,
				0xff,
				0xc3,
				0xc3,
				0xc3,
				0x66,
				0x3c,
				0x18
			},
			new byte[] {
				0x0,
				0x0,
				0xfe,
				0xc7,
				0xc3,
				0xc3,
				0xc7,
				0xfe,
				0xc7,
				0xc3,
				0xc3,
				0xc7,
				0xfe
			},
			new byte[] {
				0x0,
				0x0,
				0x7e,
				0xe7,
				0xc0,
				0xc0,
				0xc0,
				0xc0,
				0xc0,
				0xc0,
				0xc0,
				0xe7,
				0x7e
			},
			new byte[] {
				0x0,
				0x0,
				0xfc,
				0xce,
				0xc7,
				0xc3,
				0xc3,
				0xc3,
				0xc3,
				0xc3,
				0xc7,
				0xce,
				0xfc
			},
			new byte[] {
				0x0,
				0x0,
				0xff,
				0xc0,
				0xc0,
				0xc0,
				0xc0,
				0xfc,
				0xc0,
				0xc0,
				0xc0,
				0xc0,
				0xff
			},
			new byte[] {
				0x0,
				0x0,
				0xc0,
				0xc0,
				0xc0,
				0xc0,
				0xc0,
				0xc0,
				0xfc,
				0xc0,
				0xc0,
				0xc0,
				0xff
			},
			new byte[] {
				0x0,
				0x0,
				0x7e,
				0xe7,
				0xc3,
				0xc3,
				0xcf,
				0xc0,
				0xc0,
				0xc0,
				0xc0,
				0xe7,
				0x7e
			},
			new byte[] {
				0x0,
				0x0,
				0xc3,
				0xc3,
				0xc3,
				0xc3,
				0xc3,
				0xff,
				0xc3,
				0xc3,
				0xc3,
				0xc3,
				0xc3
			},
			new byte[] {
				0x0,
				0x0,
				0x7e,
				0x18,
				0x18,
				0x18,
				0x18,
				0x18,
				0x18,
				0x18,
				0x18,
				0x18,
				0x7e
			},
			new byte[] {
				0x0,
				0x0,
				0x7c,
				0xee,
				0xc6,
				0x6,
				0x6,
				0x6,
				0x6,
				0x6,
				0x6,
				0x6,
				0x6
			},
			new byte[] {
				0x0,
				0x0,
				0xc3,
				0xc6,
				0xcc,
				0xd8,
				0xf0,
				0xe0,
				0xf0,
				0xd8,
				0xcc,
				0xc6,
				0xc3
			},
			new byte[] {
				0x0,
				0x0,
				0xff,
				0xc0,
				0xc0,
				0xc0,
				0xc0,
				0xc0,
				0xc0,
				0xc0,
				0xc0,
				0xc0,
				0xc0
			},
			new byte[] {
				0x0,
				0x0,
				0xc3,
				0xc3,
				0xc3,
				0xc3,
				0xc3,
				0xc3,
				0xdb,
				0xff,
				0xff,
				0xe7,
				0xc3
			},
			new byte[] {
				0x0,
				0x0,
				0xc7,
				0xc7,
				0xcf,
				0xcf,
				0xdf,
				0xdb,
				0xfb,
				0xf3,
				0xf3,
				0xe3,
				0xe3
			},
			new byte[] {
				0x0,
				0x0,
				0x7e,
				0xe7,
				0xc3,
				0xc3,
				0xc3,
				0xc3,
				0xc3,
				0xc3,
				0xc3,
				0xe7,
				0x7e
			},
			new byte[] {
				0x0,
				0x0,
				0xc0,
				0xc0,
				0xc0,
				0xc0,
				0xc0,
				0xfe,
				0xc7,
				0xc3,
				0xc3,
				0xc7,
				0xfe
			},
			new byte[] {
				0x0,
				0x0,
				0x3f,
				0x6e,
				0xdf,
				0xdb,
				0xc3,
				0xc3,
				0xc3,
				0xc3,
				0xc3,
				0x66,
				0x3c
			},
			new byte[] {
				0x0,
				0x0,
				0xc3,
				0xc6,
				0xcc,
				0xd8,
				0xf0,
				0xfe,
				0xc7,
				0xc3,
				0xc3,
				0xc7,
				0xfe
			},
			new byte[] {
				0x0,
				0x0,
				0x7e,
				0xe7,
				0x3,
				0x3,
				0x7,
				0x7e,
				0xe0,
				0xc0,
				0xc0,
				0xe7,
				0x7e
			},
			new byte[] {
				0x0,
				0x0,
				0x18,
				0x18,
				0x18,
				0x18,
				0x18,
				0x18,
				0x18,
				0x18,
				0x18,
				0x18,
				0xff
			},
			new byte[] {
				0x0,
				0x0,
				0x7e,
				0xe7,
				0xc3,
				0xc3,
				0xc3,
				0xc3,
				0xc3,
				0xc3,
				0xc3,
				0xc3,
				0xc3
			},
			new byte[] {
				0x0,
				0x0,
				0x18,
				0x3c,
				0x3c,
				0x66,
				0x66,
				0xc3,
				0xc3,
				0xc3,
				0xc3,
				0xc3,
				0xc3
			},
			new byte[] {
				0x0,
				0x0,
				0xc3,
				0xe7,
				0xff,
				0xff,
				0xdb,
				0xdb,
				0xc3,
				0xc3,
				0xc3,
				0xc3,
				0xc3
			},
			new byte[] {
				0x0,
				0x0,
				0xc3,
				0x66,
				0x66,
				0x3c,
				0x3c,
				0x18,
				0x3c,
				0x3c,
				0x66,
				0x66,
				0xc3
			},
			new byte[] {
				0x0,
				0x0,
				0x18,
				0x18,
				0x18,
				0x18,
				0x18,
				0x18,
				0x3c,
				0x3c,
				0x66,
				0x66,
				0xc3
			},
			new byte[] {
				0x0,
				0x0,
				0xff,
				0xc0,
				0xc0,
				0x60,
				0x30,
				0x7e,
				0xc,
				0x6,
				0x3,
				0x3,
				0xff
			},
			new byte[] {
				0x0,
				0x0,
				0x3c,
				0x30,
				0x30,
				0x30,
				0x30,
				0x30,
				0x30,
				0x30,
				0x30,
				0x30,
				0x3c
			},
			new byte[] {
				0x0,
				0x3,
				0x3,
				0x6,
				0x6,
				0xc,
				0xc,
				0x18,
				0x18,
				0x30,
				0x30,
				0x60,
				0x60
			},
			new byte[] {
				0x0,
				0x0,
				0x3c,
				0xc,
				0xc,
				0xc,
				0xc,
				0xc,
				0xc,
				0xc,
				0xc,
				0xc,
				0x3c
			},
			new byte[] {
				0x0,
				0x0,
				0x0,
				0x0,
				0x0,
				0x0,
				0x0,
				0x0,
				0x0,
				0xc3,
				0x66,
				0x3c,
				0x18
			},
			new byte[] {
				0xff,
				0xff,
				0x0,
				0x0,
				0x0,
				0x0,
				0x0,
				0x0,
				0x0,
				0x0,
				0x0,
				0x0,
				0x0
			},
			new byte[] {
				0x0,
				0x0,
				0x0,
				0x0,
				0x0,
				0x0,
				0x0,
				0x0,
				0x0,
				0x18,
				0x38,
				0x30,
				0x70
			},
			new byte[] {
				0x0,
				0x0,
				0x7f,
				0xc3,
				0xc3,
				0x7f,
				0x3,
				0xc3,
				0x7e,
				0x0,
				0x0,
				0x0,
				0x0
			},
			new byte[] {
				0x0,
				0x0,
				0xfe,
				0xc3,
				0xc3,
				0xc3,
				0xc3,
				0xfe,
				0xc0,
				0xc0,
				0xc0,
				0xc0,
				0xc0
			},
			new byte[] {
				0x0,
				0x0,
				0x7e,
				0xc3,
				0xc0,
				0xc0,
				0xc0,
				0xc3,
				0x7e,
				0x0,
				0x0,
				0x0,
				0x0
			},
			new byte[] {
				0x0,
				0x0,
				0x7f,
				0xc3,
				0xc3,
				0xc3,
				0xc3,
				0x7f,
				0x3,
				0x3,
				0x3,
				0x3,
				0x3
			},
			new byte[] {
				0x0,
				0x0,
				0x7f,
				0xc0,
				0xc0,
				0xfe,
				0xc3,
				0xc3,
				0x7e,
				0x0,
				0x0,
				0x0,
				0x0
			},
			new byte[] {
				0x0,
				0x0,
				0x30,
				0x30,
				0x30,
				0x30,
				0x30,
				0xfc,
				0x30,
				0x30,
				0x30,
				0x33,
				0x1e
			},
			new byte[] {
				0x7e,
				0xc3,
				0x3,
				0x3,
				0x7f,
				0xc3,
				0xc3,
				0xc3,
				0x7e,
				0x0,
				0x0,
				0x0,
				0x0
			},
			new byte[] {
				0x0,
				0x0,
				0xc3,
				0xc3,
				0xc3,
				0xc3,
				0xc3,
				0xc3,
				0xfe,
				0xc0,
				0xc0,
				0xc0,
				0xc0
			},
			new byte[] {
				0x0,
				0x0,
				0x18,
				0x18,
				0x18,
				0x18,
				0x18,
				0x18,
				0x18,
				0x0,
				0x0,
				0x18,
				0x0
			},
			new byte[] {
				0x38,
				0x6c,
				0xc,
				0xc,
				0xc,
				0xc,
				0xc,
				0xc,
				0xc,
				0x0,
				0x0,
				0xc,
				0x0
			},
			new byte[] {
				0x0,
				0x0,
				0xc6,
				0xcc,
				0xf8,
				0xf0,
				0xd8,
				0xcc,
				0xc6,
				0xc0,
				0xc0,
				0xc0,
				0xc0
			},
			new byte[] {
				0x0,
				0x0,
				0x7e,
				0x18,
				0x18,
				0x18,
				0x18,
				0x18,
				0x18,
				0x18,
				0x18,
				0x18,
				0x78
			},
			new byte[] {
				0x0,
				0x0,
				0xdb,
				0xdb,
				0xdb,
				0xdb,
				0xdb,
				0xdb,
				0xfe,
				0x0,
				0x0,
				0x0,
				0x0
			},
			new byte[] {
				0x0,
				0x0,
				0xc6,
				0xc6,
				0xc6,
				0xc6,
				0xc6,
				0xc6,
				0xfc,
				0x0,
				0x0,
				0x0,
				0x0
			},
			new byte[] {
				0x0,
				0x0,
				0x7c,
				0xc6,
				0xc6,
				0xc6,
				0xc6,
				0xc6,
				0x7c,
				0x0,
				0x0,
				0x0,
				0x0
			},
			new byte[] {
				0xc0,
				0xc0,
				0xc0,
				0xfe,
				0xc3,
				0xc3,
				0xc3,
				0xc3,
				0xfe,
				0x0,
				0x0,
				0x0,
				0x0
			},
			new byte[] {
				0x3,
				0x3,
				0x3,
				0x7f,
				0xc3,
				0xc3,
				0xc3,
				0xc3,
				0x7f,
				0x0,
				0x0,
				0x0,
				0x0
			},
			new byte[] {
				0x0,
				0x0,
				0xc0,
				0xc0,
				0xc0,
				0xc0,
				0xc0,
				0xe0,
				0xfe,
				0x0,
				0x0,
				0x0,
				0x0
			},
			new byte[] {
				0x0,
				0x0,
				0xfe,
				0x3,
				0x3,
				0x7e,
				0xc0,
				0xc0,
				0x7f,
				0x0,
				0x0,
				0x0,
				0x0
			},
			new byte[] {
				0x0,
				0x0,
				0x1c,
				0x36,
				0x30,
				0x30,
				0x30,
				0x30,
				0xfc,
				0x30,
				0x30,
				0x30,
				0x0
			},
			new byte[] {
				0x0,
				0x0,
				0x7e,
				0xc6,
				0xc6,
				0xc6,
				0xc6,
				0xc6,
				0xc6,
				0x0,
				0x0,
				0x0,
				0x0
			},
			new byte[] {
				0x0,
				0x0,
				0x18,
				0x3c,
				0x3c,
				0x66,
				0x66,
				0xc3,
				0xc3,
				0x0,
				0x0,
				0x0,
				0x0
			},
			new byte[] {
				0x0,
				0x0,
				0xc3,
				0xe7,
				0xff,
				0xdb,
				0xc3,
				0xc3,
				0xc3,
				0x0,
				0x0,
				0x0,
				0x0
			},
			new byte[] {
				0x0,
				0x0,
				0xc3,
				0x66,
				0x3c,
				0x18,
				0x3c,
				0x66,
				0xc3,
				0x0,
				0x0,
				0x0,
				0x0
			},
			new byte[] {
				0xc0,
				0x60,
				0x60,
				0x30,
				0x18,
				0x3c,
				0x66,
				0x66,
				0xc3,
				0x0,
				0x0,
				0x0,
				0x0
			},
			new byte[] {
				0x0,
				0x0,
				0xff,
				0x60,
				0x30,
				0x18,
				0xc,
				0x6,
				0xff,
				0x0,
				0x0,
				0x0,
				0x0
			},
			new byte[] {
				0x0,
				0x0,
				0xf,
				0x18,
				0x18,
				0x18,
				0x38,
				0xf0,
				0x38,
				0x18,
				0x18,
				0x18,
				0xf
			},
			new byte[] {
				0x18,
				0x18,
				0x18,
				0x18,
				0x18,
				0x18,
				0x18,
				0x18,
				0x18,
				0x18,
				0x18,
				0x18,
				0x18
			},
			new byte[] {
				0x0,
				0x0,
				0xf0,
				0x18,
				0x18,
				0x18,
				0x1c,
				0xf,
				0x1c,
				0x18,
				0x18,
				0x18,
				0xf0
			},
			new byte[] {
				0x0,
				0x0,
				0x0,
				0x0,
				0x0,
				0x0,
				0x6,
				0x8f,
				0xf1,
				0x60,
				0x0,
				0x0,
				0x0
			}
		};

		private static readonly byte[] nonascii = {
			0xff,
			0xff,
			0xff,
			0xff,
			0xff,
			0xff,
			0xff,
			0xff,
			0xff,
			0xff,
			0xff,
			0xff,
			0xff
		};
	}
}

//=======================================================
//Service provided by Telerik (www.telerik.com)
//Conversion powered by NRefactory.
//Twitter: @telerik
//Facebook: facebook.com/telerik
//=======================================================
